package com.ouyunc.oauth2.config;

import cn.hutool.core.date.SystemClock;
import cn.hutool.crypto.SmUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author fangzhenxun
 * @date 2019/11/5 14:10
 * @description security 密码加密配置类,注意：非对称加密是非常耗时的
 */
@Configuration
public class PasswordEncoderConfig {
    protected final Logger log = LoggerFactory.getLogger(PasswordEncoderConfig.class);


    /**
     * @Author fangzhenxun
     * @Description  默认密码加密，使用springsecurity 底层封装的BCryptPasswordEncoder，
     * @Date  2019/11/5 14:12
     * @Param []
     * @return org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
     **/
    @Bean
    public PasswordEncoder defaultPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * @Author fangzhenxun
     * @Description  自定义加密的方式，使用国密SM3 方式进行加密
     * @Date  2019/11/5 14:14
     * @Param []
     * @return org.springframework.security.crypto.password.PasswordEncoder
     **/
    @Primary
    @Bean
    public PasswordEncoder iPasswordEncoder() {
        return new PasswordEncoder() {

            /**
             * 对表单原始密码rawPassword进行加密,注意这里使用国密3 加密会首次耗时600毫秒左右
             **/
            @Override
            public String encode(CharSequence rawPassword) {
                long beginTime = SystemClock.now();
                log.info("开始加密...{}",rawPassword);
                String sm3 = SmUtil.sm3(String.valueOf(rawPassword));
                log.info("加密完成，共耗时：{}ms", (SystemClock.now() - beginTime));
                return sm3;
            }

            /**
             * 验证从存储中获取的编码密码encodedPassword，也对提交的原始密码rawPassword进行编码。
             **/
            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return encode(rawPassword).equals(encodedPassword);
            }
        };
    }

}
